﻿using System;
using System.Collections.Generic;
using System.Web.UI;
using System.Web.UI.WebControls;
using ReadyApps.Common;
using ReadyApps.Common.Exceptions;
using ReadyApps.Data;
using ReadyApps.Data.Wiki;
using ReadyApps.Wiki.Templates;

namespace ReadyApps.Wiki.Views
{
    class PendingView : ContentViewBase, IViewFiresTitleSetEvent
    {
        #region Variables and Constants

        private PageDetails pageDetails;
        private IWikiSecurityManager securityManager;

        #endregion

        #region Events

        private event EventHandler viewCurrentButtonClick;
        public event EventHandler ViewCurrentButtonClick
        {
            add { viewCurrentButtonClick += value; }
            remove { viewCurrentButtonClick -= value; }
        }

        private event EventHandler publishButtonClick;
        public event EventHandler PublishButtonClick
        {
            add { publishButtonClick += value; }
            remove { publishButtonClick -= value; }
        }

        private event EventHandler deleteButtonClick;
        public event EventHandler DeleteButtonClick
        {
            add { deleteButtonClick += value; }
            remove { deleteButtonClick -= value; }
        }

        private event EventHandler editButtonClick;
        public event EventHandler EditButtonClick
        {
            add { editButtonClick += value; }
            remove { editButtonClick -= value; }
        }

        #endregion

        #region Constructor

        public PendingView(int wikiPageID, PageDetails wikiPageDetails, WikiControlSettings wikiControlSettings,
            IWikiDataProvider wikiDataProvider, IWikiUrlManager wikiUrlManager, IWikiSecurityManager wikiSecurityManager)
            : base(wikiPageID, wikiControlSettings, wikiDataProvider, wikiUrlManager)
        {
            if (wikiPageDetails == null)
            {
                throw new ArgumentNullException("wikiPageDetails");
            }
            if (wikiSecurityManager == null)
            {
                throw new ArgumentNullException("wikiSecurityManager");
            }
            pageDetails = wikiPageDetails;
            securityManager = wikiSecurityManager;
        }

        #endregion

        #region Public Methods

        public override void BuildControlTree(ControlCollection controls, bool raiseEvents)
        {
            Control container = new Control();

            // Instantiate the template
            ITemplate layoutTemplate = controlSettings.LayoutTemplate ?? new WikiDefaultLayoutTemplate();
            layoutTemplate.InstantiateIn(container);

            // Locate the content and wiki controls control
            Control contentControl = WebUtilities.FindControlRecursive(container, WikiController.CONTENT_CONTROL_ID);
            if (contentControl == null)
            {
                throw new MissingControlException(WikiController.CONTENT_CONTROL_ID, location: "layout template");
            }
            Control controlsControl = WebUtilities.FindControlRecursive(container, WikiController.CONTROLS_CONTROL_ID);
            if (controlsControl == null)
            {
                throw new MissingControlException(WikiController.CONTROLS_CONTROL_ID, location: "layout template");
            }

            // Lookup page info
            PageContent content = dataProvider.GetPageContentForPending(pageID);

            // Fill the page content
            GetContentControls(content, contentControl);

            // Display the wiki controls that the user has access to
            List<WikiControlButton> options = GetAvailableOptions();
            for (int i = 0; i < options.Count; i++)
            {
                if (i != 0)
                {
                    controlsControl.Controls.Add(new Literal() { Text = WikiController.BUTTON_SPACER });
                }
                controlsControl.Controls.Add(options[i].RootControl);
            }
            controlsControl.Controls.Add(new Literal() { Text = "<br />" });
            Label pendingLabel = new Label();
            pendingLabel.Text = "This is a pending version";
            pendingLabel.ForeColor = System.Drawing.Color.Firebrick;
            pendingLabel.Font.Bold = true;
            controlsControl.Controls.Add(pendingLabel);

            controls.Clear();
            controls.Add(container);

            if (raiseEvents)
            {
                controlSettings.OnTitleSet(this, new TitleSetEventArgs(content.Title));
            }
        }

        #endregion

        #region Private Methods

        private List<WikiControlButton> GetAvailableOptions()
        {
            List<WikiControlButton> options = new List<WikiControlButton>(4);

            if (securityManager.CanManagePublishing)
            {
                WikiControlButton publishPage = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
                publishPage.ButtonControl.Text = "Publish";
                publishPage.ButtonControl.Click += publishButtonClick;
                options.Add(publishPage);

                WikiControlButton deleteRevision = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
                deleteRevision.ButtonControl.Text = "Delete";
                deleteRevision.ButtonControl.Click += deleteButtonClick;
                options.Add(deleteRevision);
            }

            if (securityManager.CanEditPage &&
                (securityManager.CanManagePublishing || securityManager.IsSameUser(pageDetails.PendingRevisionAuthor)))
            {
                WikiControlButton editPage = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
                editPage.ButtonControl.Text = "Edit";
                editPage.ButtonControl.Click += editButtonClick;
                options.Add(editPage);
            }

            WikiControlButton viewPending = WikiControlButton.GetFromTemplate(controlSettings.ButtonTemplate);
            viewPending.ButtonControl.Text = "View Current";
            viewPending.ButtonControl.Click += viewCurrentButtonClick;
            options.Add(viewPending);

            return options;
        }

        #endregion
    }
}
